package study.线程池.原子操作;

import com.alibaba.fastjson2.JSONObject;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @Author 刘伟涛
 * @Date 2023/12/7 11:13
 **/
public class Demo {
    static int number = 20;
    static final Integer KEY = 2;
    static final Demo demo = new Demo();

    public static void main(String[] args) {

/*        List<Test> testList = new ArrayList<>();
        AtomicLong atomicLong = new AtomicLong();
        GenerateId generateId = new GenerateId(atomicLong);
        int num = 0;
        for (int i = 1; i <= 20; i++) {
            int finalI = i;
            new Thread(() -> {
                if (finalI == 3) {
                    System.out.println("睡三秒");
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                synchronized (KEY){
                    Demo.add();
                    Test test = new Test(finalI, number);
                    testList.add(test);
                    System.out.println(number + "---------------------(" + finalI + ")");
                }
            }).start();
            num = i;
        }
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if(num == 20){
            testList.sort(Comparator.comparing(Test::getNumber));
            System.out.println(JSONObject.toJSONString(testList));
        }*/

        AtomicLong atomicLong = new AtomicLong();
        GenerateId id = new GenerateId(atomicLong);
        for (int i = 0; i < 20; i++) {
            new Thread(() -> {
                System.out.println(id.getId());
            }).start();
        }


    }

    static void add() {
        int a = number;
        if(a == 28){
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        a++;
        number = a;
    }
}


class GenerateId{
    AtomicLong atomicLong;

    public GenerateId(AtomicLong atomicLong) {
        this.atomicLong = atomicLong;
    }

    long getId() {
        //通过CAS自旋操作，保证不会出现重复的值
        //自旋：当多线程调用导致内存值已被修改，与prev不一致时，不会返回自增值，而是do...while循环，
        //再取获取内存值，将内存值赋值给prev，进行修改时，再对比内存值和prev，如果相同则修改。
        return this.incrementAndGet(atomicLong);
    }

    public long incrementAndGet(AtomicLong var) {
        long prev, next;
        int i = 0;
        do {
            prev = var.get();

            //要执行的任务，当执行的时间过长时，从var获取的值可能与prev不相同，因为多线程可能已经修改
            i++;
            next = prev + 1;
            System.out.println(next + "自旋：" + i + "次");
            //compareAndSet在进行对比prev值与内存值。
        } while (!var.compareAndSet(prev, next));
        return next;
    }
}

class Test{
    int i;
    int number;

    public Test(int i, int number) {
        this.i = i;
        this.number = number;
    }

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }

    public int getNumber() {
        return number;
    }
}
